<!--
 * dscription: 简易表格组件 在编辑状态下支持input select 组件
-->
<template>
  <div class="smpleTable">
    <div class="mask-container" v-if="isMask"></div>
    <Table
      :columns="G_columns"
      :data="data"
      draggable
      stripe
      @on-drag-drop="onRowDblclick"
      ref="smpleTable"
    >
      <template
        v-for="(item, idx) in columns"
        slot-scope="{ row, index }"
        :slot="item.slot"
      >
        <Input
          :key="idx"
          type="text"
          v-model="row[item.slot]"
          v-if="G_editIndex === index && item.editComp.type === 'input'"
          @on-change="argNameOnChange($event, row, item.slot)"
        />

        <Select
          :key="idx"
          :transfer="true"
          label-in-value
          v-model="row[item.slot]"
          @on-change="argDataTypeSelectOnChange($event, row, item.slot)"
          v-else-if="G_editIndex === index && item.editComp.type === 'select'"
        >
          <Option
            label-in-value
            v-for="itm in item.editComp.selectList"
            :value="itm.value"
            :key="itm.value"
            >{{ itm.label }}</Option
          >
        </Select>

        <o-m2o-selector
          :key="idx"
          v-else-if="G_editIndex === index && item.editComp.type === 'm2o'"
          v-model="row[item.slot]"
          :placeholder="$srv.getI18nByValue('选择用户')"
          @on-dochange="
            m2oOnChange($event, row, item.slot, item.editComp.props.vField)
          "
          :tTable="item.editComp.props.tTable"
          :tField="item.editComp.props.tField"
          :dropdown="true"
        ></o-m2o-selector>
        <!-- :vField="item.editComp.props.vField" -->
        <!-- v-model=row[item.slot] ————> {value:'',label:''} -->
        <!-- :filter="eventFilter" -->

        <i-switch
          :key="idx"
          v-model="row[item.slot]"
          @on-change="argDataTypeSwitchOnChange($event, row, item.slot)"
          v-else-if="G_editIndex === index && item.editComp.type === 'switch'"
        />

        <span :key="idx" v-else>{{
          item.editComp.type === 'select'
            ? row[`${item.slot}_label`]
            : item.editComp.type === 'm2o'
            ? row[`${item.slot}_label`]
            : row[item.slot]
        }}</span>
        <!-- ? row[item.slot]['label'] -->
      </template>

      <template slot-scope="{ row, index }" slot="action" v-if="allowEdit">
        <div v-if="G_editIndex === index">
          <Button
            @click="handleSave(row, index)"
            shape="circle"
            icon="md-checkmark"
          />
          <Button
            @click="handleCanel(row, index)"
            shape="circle"
            icon="md-close"
          />
        </div>
        <div v-else>
          <Button
            :disabled="disabled && !onlyEdit"
            @click="handleEdit(row, index)"
            shape="circle"
            icon="ios-create-outline"
          />

          <Button
            :disabled="disabled"
            @click="handleDelete(row, index)"
            shape="circle"
            style="color: red"
            icon="md-remove"
          />
        </div>
      </template>
    </Table>
    <div
      class="newRowBox ivu-icon ivu-icon-md-add"
      @click="onNewRow"
      :class="[{ disabled: disabled }]"
    ></div>
  </div>
</template>
<script lang="ts">
import { ifs, T_srv, ts, Tsrv, vue } from './config';

@T_srv.comp
export default class T_smpleTable extends vue {
  @T_srv.prop({ required: true }) columns: Array<any>;

  @T_srv.prop({ required: false, default: () => [] }) data: Array<any>;

  // 允许编辑
  @T_srv.prop({ default: true }) allowEdit: boolean;

  // 仅允许编辑（编辑按钮）
  @T_srv.prop({ default: false }) onlyEdit: boolean;

  // 是否可用
  @T_srv.prop({ default: true }) disabled: boolean;

  @T_srv.ref(`smpleTable`) smpleTableRef: any;

  @T_srv.watch(`disabled`, { immediate: true, deep: false })
  onReadonly(val: boolean, oldVal: boolean) {
    // 得到只读信息时强制退出input状态
    if (val === true) {
      this.G_editIndex = -1;
    }
  }

  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  private G_compName: string = 'smleTable';

  private GT_compBoxInfo: ifs.I_compBoxInfo;

  private G_minimap: any = null;

  private G_compID: string;

  // 编辑标致在表格编辑互动中以此控制用
  private G_editIndex: number = -1;

  // 传入档位设置，在尾部有范例说明
  private G_columns = [];

  // 旧值记录地图，在放弃修改时的临时缓冲
  private G_oldRowMap = new Map();

  private GT_compBox: ifs.I_compBox;

  public isMask: boolean = false;

  created() {
    this.G_compID = Tsrv.utils.getGUID();
    /* 如果外部有传入组件信息 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox = new ts.T_compBox(this.G_compID); // 使用本地实例
    } else {
      this.G_compID = this.compBoxInfo.compID;
      this.GT_compBox = this.compBoxInfo.TcompBox;
    }
    this.GT_compBoxInfo = { compID: this.G_compID, TcompBox: this.GT_compBox };

    this.handleData();
    if (this.columns.length > 0 && this.allowEdit) {
      const L_arr = Tsrv.utils.clone(this.columns);
      L_arr.forEach(el => {
        el.title = Tsrv.getI18nBySrv(el.title);
      });
      // 加入控制按扭字段
      L_arr.push({ title: Tsrv.getI18nByValue('操作'), slot: 'action' });
      this.G_columns = L_arr;
    }
  }

  mounted() {
    /* 向父组件发送实例 */
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);

    /* 最终应用组件向外抛出引用实例,以供应用间调用 */
    // Tsrv.compBox.addCompMergeName(
    //   Tsrv.compBox.getDefGUID(), // 全局compBox
    //   '????',
    //   this,
    //   '???'
    // );
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 最终应用组件销毁 */
    /* this.GT_compBox.removeCompMergeName(this.G_compID, 'devBom','funName'); */

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 当为select 组件时， 将select value 对应的label 插入数组 取名为[字段名_label]
   */

  handleData() {
    const self = this;
    // for (let obj of self.columns) {
    //   if (obj.editComp.type === `select`) {
    //     self.data.forEach(item => {
    //       if (item[obj.slot]) {
    //         item[`${obj.slot}_label`] = obj.editComp.selectList.filter(
    //           itm => itm.value === item[obj.slot]
    //         )[0].label;
    //       }
    //     });
    //   }
    // }
  }
  /**
   * @Author: wiz
   * @param {*} row
   * @param {*} index
   * @return {*}
   * @description: 编辑处理
   */

  private handleEdit(row, index) {
    // 如果有其它行未保存，则不可编辑新行
    if (this.G_oldRowMap.size > 0) {
      return;
    }

    // 记录旧值
    this.G_oldRowMap.set(index, Tsrv.utils.clone(row));
    this.G_editIndex = index;
  }
  /**
   * @Author: wiz
   * @param {*} row
   * @param {*} index
   * @return {*}
   * @description: 取消处理
   */

  private handleCanel(row, index) {
    if (this.G_oldRowMap.has(index)) {
      Tsrv.utils.listAssign(this.G_oldRowMap.get(index), row);
      this.G_oldRowMap.delete(index);
    }
    this.G_editIndex = -1;
  }
  /**
   * @Author: wiz
   * @param {*} row
   * @param {*} index
   * @return {*}
   * @description: 保存处理
   */

  private handleSave(row, index) {
    if (this.G_oldRowMap.has(index)) {
      this.G_oldRowMap.delete(index);
    }
    this.data[index] = row;
    Tsrv.utils.listAssign(row, this.data[index]);
    this.G_editIndex = -1;
    this.$emit(`onSaveRow`, { data: this.data, row, index });
  }
  /**
   * @Author: wiz
   * @param {*} index
   * @return {*}
   * @description: 删除处理
   */

  private handleDelete(row, index) {
    Tsrv.utils.remove(this.data, index);
    this.$emit(`onDelRow`, { data: this.data, row, index });
  }
  /**
   * @Author: wiz
   * @param {*} row
   * @param {*} index
   * @return {*}
   * @description: 新增一行处理
   */

  private handleNewRow(row, index) {
    this.onNewRow();
    this.$emit(`onNewRow`, { data: this.data, row, index });
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 新增一行
   */

  onNewRow() {
    if (this.disabled) {
      return;
    }

    this.handleEdit({}, this.data.push({}) - 1);
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 行双击
   */

  private onRowDblclick(P_e) {
    this.$emit(`onRowDblclick`, P_e);
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 选择改变同时改变对应label
   */

  private argDataTypeSelectOnChange(v, row, key) {
    row[`${key}_label`] = v.label;
  }

  private argNameOnChange(v, row, key) {}

  private argDataTypeSwitchOnChange(v, row, key) {}

  private m2oOnChange(v, row, field, labelField) {
    // row[field]['label'] = v[labelField];
    row[`${field}_label`] = v[labelField];
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 外部ref调用函数
   */

  outData() {
    return this.data;
  }

  getData() {
    return this.outData();
  }

  setData(data) {
    this.data.length = 0;
    this.data.push(...data);
  }
}
</script>
<style lang="scss" scoped>
.smpleTable .disabled {
  color: rgba(0, 0, 0, 0.25);
  cursor: not-allowed;
}
.newRowBox {
  margin-left: 50%;
  margin-bottom: 10px;
  margin-left: 50%;

  width: 20px;
  height: 15px;
  border: 1px solid #eaebef;
  cursor: pointer;
  border-radius: 0 0 10px 10px;
  border-top: none;
  box-shadow: 0 2px 10px #888888;
  color: #2d8eff;
}
</style>
<!-- 
栏位配置
  [
    {
      title: "参数名",
      slot: "outName",  //iview插槽模式 也是字段名
      editComp: {
        type: "input"  //在编辑模式下的input组件
      }
    },
    {
    title: '参数名',
    slot: 'NotNull',  //iview插槽模式 也是字段名
    key: 'NotNull',   //设置单元格样式时，iview通过key定位
    editComp: {
      type: 'switch'  //在编辑模式下的switch组件
      }
    },
    {
      title: "数据类型",
      slot: "outDataType",
      editComp: {
        type: "select",
        //此为选择value number smpleTable会自动处理将此列表数据加入data并新增一个 slot +  _label 的字段数据
        selectList: [
          {
            value: "string",
            label: "字符"
          },
          {
            value: "number",
            label: "数字"
          },
          {
            value: "dataTime",
            label: "日期时间"
          },
          {
            value: "boolean",
            label: "布尔"
          }
        ]
      }
    },
  ];

  data 数据格式
  [
      { col1: "", col2: "number" }
      假如col2是select组件,则data会加入label字段无需外部处理  { col1: "", col2: "number"，col2_lablel:"数字" }
     
    ];

-->
